//------------------------------------------------------------------------------
//
//   author: 小兵（aosnow@yeah.net）
//   create: 2012-5-29 下午5:11:19
//    class: LoaderBase - 加载器基础类
//
//------------------------------------------------------------------------------

package starfire.rpc.loader.elements
{
	import starfire.events.LoaderEvent;
	import starfire.rpc.loader.LoadMessage;
	import starfire.rpc.loader.LoadState;
	import starfire.rpc.loader.MediaCache;

	import flash.display.Loader;
	import flash.errors.IllegalOperationError;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;

	[ExcludeClass]
	public class LoaderBase extends EventDispatcher
	{
		/** 加载完成回调函数  **/
		public var complete:Function;

		/** 加载错误回调函数  **/
		public var error:Function;

		/** 加载过程回调函数  **/
		public var progress:Function;

		/** 加载任务描述信息  **/
		private var _message:LoadMessage;

		/** 当前状态  **/
		private var state:int;

		public function LoaderBase( message:LoadMessage )
		{
			_message = message;
		}

		//--------------------------------------------------------------------------
		//
		//   是否符合加载要求
		//
		//--------------------------------------------------------------------------

		public function canHandleResource():Boolean
		{
			return false;
		}

		//--------------------------------------------------------------------------
		//
		//   加载描述信息
		//
		//--------------------------------------------------------------------------

		public function get message():LoadMessage
		{
			return _message;
		}

		//--------------------------------------------------------------------------
		//
		//   子类实现加载和卸载功能
		//
		//--------------------------------------------------------------------------

		public final function load():void
		{
			validateLoad( message );
			executeLoad( message );
		}

		public final function unload():void
		{
			executeUnload( message );

			complete = null;
			error = null;
			progress = null;
			_message = null;
		}

		private function validateLoad( message:LoadMessage ):void
		{
			if( message == null )
			{
				throw new IllegalOperationError( "ERROR: 未设置正确的加载描述信息！" );
			}

			if( message.loadState == LoadState.READY )
			{
				throw new IllegalOperationError( "WARNING: 资源已经加载过！" );
			}

			if( message.loadState == LoadState.LOADING )
			{
				throw new IllegalOperationError( "ERROR: 资源正在加载..." );
			}

//			if( canHandleResource() == false )
//			{
//				throw new IllegalOperationError( "ERROR: 错误的加载源，该加载器无法加载 " + message.url );
//			}
		}

		protected function executeLoad( message:LoadMessage ):void
		{
		}

		protected function executeUnload( message:LoadMessage ):void
		{
		}

		//--------------------------------------------------------------------------
		//
		//   状态更新
		//
		//--------------------------------------------------------------------------

		/**
		 * 更新当前加载状态
		 * @param newState				- 新状态
		 */
		protected final function updateLoadState( newState:String ):void
		{
			if( newState != message.loadState )
			{
				var oldState:String = message.loadState;

				if( hasEventListener( LoaderEvent.LOAD_STATE_CHANGE ))
					dispatchEvent( new LoaderEvent( LoaderEvent.LOAD_STATE_CHANGE, this, message, oldState, newState ));
			}
		}

		//--------------------------------------------------------------------------
		//
		//   资源加载后的数据处理
		//
		//--------------------------------------------------------------------------

		protected final function saveCache( data:Object ):void
		{
			MediaCache.cacheResource( message, data );
		}

		//--------------------------------------------------------------------------
		//
		//   资源加载相关事件处理
		//
		//--------------------------------------------------------------------------

		/**
		 * 切换添加和移除加载对象的事件
		 * @param loader				- 加载对象（必须是Loader或者URLLoader对象）
		 * @param on					- 是否添加（true - 添加；false - 移除）
		 */
		protected final function toggleLoaderListeners( loader:Object, on:Boolean ):void
		{
			if( loader is Loader )
				loader = loader.contentLoaderInfo;

			if( on )
			{
				loader.addEventListener( Event.COMPLETE, loadCompleteHandler );
				loader.addEventListener( ProgressEvent.PROGRESS, progressHandle );
				loader.addEventListener( IOErrorEvent.IO_ERROR, IOErrorHandler );
				loader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler );
			}
			else
			{
				loader.removeEventListener( Event.COMPLETE, loadCompleteHandler );
				loader.removeEventListener( ProgressEvent.PROGRESS, progressHandle );
				loader.removeEventListener( IOErrorEvent.IO_ERROR, IOErrorHandler );
				loader.removeEventListener( SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler );
			}
		}

		protected function loadCompleteHandler( event:Event ):void
		{
			if( complete is Function )
			{
				complete( event );
			}
		}

		protected function IOErrorHandler( event:IOErrorEvent, detail:String = null ):void
		{
			if( error is Function )
			{
				error( event ? event.text : detail );
			}

			trace( "[IOError]", this, detail ? detail : event.text );
			updateLoadState( LoadState.LOAD_ERROR );
		}

		protected function securityErrorHandler( event:SecurityErrorEvent, detail:String = null ):void
		{
			if( error is Function )
			{
				error( event ? event.text : detail );
			}

			trace( "[SecurityError]", this, detail ? detail : event.text );
			updateLoadState( LoadState.LOAD_ERROR );
		}

		protected function progressHandle( event:ProgressEvent ):void
		{
			if( progress is Function )
			{
				progress( event );
			}
		}
	}
}
